package statistics;

import java.util.ArrayList;

public class LinearRegression 
{ 
	ArrayList<Double> x = new ArrayList<Double>();
	ArrayList<Double> y = new ArrayList<Double>();
	private double m = 0;
	private double b = 0;
	double xxbar = 0.0, yybar = 0.0, xybar = 0.0;
	double rss = 0.0;      // residual sum of squares
    double ssr = 0.0;      // regression sum of squares
	

	public double getRss() {
		return rss;
	}

	public void setRss(double rss) {
		this.rss = rss;
	}

	public double getSsr() {
		return ssr;
	}

	public void setSsr(double ssr) {
		this.ssr = ssr;
	}

	public double getXxbar() {
		return xxbar;
	}

	public void setXxbar(double xxbar) {
		this.xxbar = xxbar;
	}

	public double getYybar() {
		return yybar;
	}

	public void setYybar(double yybar) {
		this.yybar = yybar;
	}

	public double getXybar() {
		return xybar;
	}

	public void setXybar(double xybar) {
		this.xybar = xybar;
	}

	public LinearRegression(ArrayList<Double> x, ArrayList<Double> y)
	{
		this.x = x;
		this.y = y;
	}
	
	public void compute()
	{
        // first pass: read in data, compute xbar and ybar
        double sumx = 0.0, sumy = 0.0, sumx2 = 0.0;
        
        for (int i=0;i<x.size();i++)
        {
        	sumx  += x.get(i);
            sumx2 += x.get(i) * x.get(i);
            sumy  += y.get(i);
        }

        double xbar = sumx / x.size();
        double ybar = sumy / x.size();

        // second pass: compute summary statistics
        for (int i = 0; i < x.size(); i++) 
        {
            xxbar += (x.get(i) - xbar) * (x.get(i) - xbar);
            yybar += (y.get(i) - ybar) * (y.get(i) - ybar);
            xybar += (x.get(i) - xbar) * (y.get(i) - ybar);
        }
        
        double beta1 = xybar / xxbar;
        double beta0 = ybar - beta1 * xbar;

        // print results
        System.out.println("y   = " + beta1 + " * x + " + beta0);
        m = beta1;
        b = beta0;

        // analyze results
        int df = x.size() - 2;
        for (int i = 0; i < x.size(); i++) {
            double fit = beta1*x.get(i) + beta0;
            rss += (fit - y.get(i)) * (fit - y.get(i));
            ssr += (fit - ybar) * (fit - ybar);
        }
        double R2    = ssr / yybar;
        double svar  = rss / df;
        double svar1 = svar / xxbar;
        double svar0 = svar/x.size() + xbar*xbar*svar1;
        System.out.println("R^2                 = " + R2);
        System.out.println("std error of beta_1 = " + Math.sqrt(svar1));
        System.out.println("std error of beta_0 = " + Math.sqrt(svar0));
        svar0 = svar * sumx2 / (x.size() * xxbar);
        System.out.println("std error of beta_0 = " + Math.sqrt(svar0));

        System.out.println("SSTO = " + yybar);
        System.out.println("SSE  = " + rss);
        System.out.println("SSR  = " + ssr);
	}

	public double getM() {
		return m;
	}

	public void setM(double m) {
		this.m = m;
	}

	public double getB() {
		return b;
	}

	public void setB(double b) {
		this.b = b;
	}
    
}
